﻿using Furion;
using Furion.DependencyInjection;
using LS.Nc6.Application.System;
using LS.Nc6.Core;
using LS.Nc6.Core.Entity.System;
using LS.Nc6.Web.Entry.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Options;

namespace LS.Nc6.Web.Entry.Controllers
{
    [Authorize]

    public class BaseAdminController : Controller
    {
        protected SysUserModel UserInfo
        {
            get; set;
        }


        public List<SysMenuModel> CurentMenu { get; set; }

        private readonly ICache _cache;

       
        public BaseAdminController(IOptions<CacheOptions> cacheOptions, Func<string, ISingleton, object> resolveNamed)
        {
            _cache = resolveNamed(cacheOptions.Value.CacheType.ToString(), default) as ICache;
        }

        public Dictionary<string, List<string>> CurentMenuPower { get; set; }


        public override void OnActionExecuting(ActionExecutingContext context)
        {
            string userid = GetUserId();
           
            if (!string.IsNullOrEmpty(userid))
            {
                if (userid == "0")
                {
                    context.Result = new RedirectToRouteResult(new RouteValueDictionary(
                                 new
                                 {
                                     controller = "Error",
                                     action = "NotCustFound"
                                 }));
                }
                else
                {
                    UserInfo = new SysUserModel
                    {
                        ID = userid.ParseToLong(),
                        UserName = GetUserName(),
                        RealName = GetRealName(),
                        UserType = GetUserType().ParseToInt(),
                    };
                    if (_cache.Get<List<SysMenuModel>>("CurentMenu_" + userid) != null && _cache.Get<List<SysMenuModel>>("CurentMenu_" + userid).Count > 0)
                    {
                        CurentMenu = _cache.Get<List<SysMenuModel>>("CurentMenu_" + userid);
                        CurentMenuPower = _cache.Get<Dictionary<string, List<string>>>("CurentPower_" + userid);
                    }
                    else
                    {
                        GetUserMenu(userid);
                    }
                    ViewBag.CurentMenuPower = CurentMenuPower;
                    base.OnActionExecuting(context);
                }
               
            }
        }

        /// <summary>
        /// 获取系统配置
        /// </summary>
        /// <returns></returns>
        public async Task<SysInfoModel> SysInfoModelCache()
        {
            return await _cache.GetAsync<SysInfoModel>("LS_Nc6_SysInfo");
        }


        #region 错误跳转
    /// <summary>
    /// 无效的响应
    /// </summary>
    /// <returns></returns>
    protected ActionResult ErrorInvalidResponse()
        {
            return new RedirectResult("/Error/InvalidResponse");
            
        }
        /// <summary>
        /// 其它错误
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorOther()
        {
            return new RedirectResult("/Error/Other");
   
        }
        /// <summary>
        ///服务器内部
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorServerInternal()
        {
            return new RedirectResult("/Error/ServerInternal");
        }
        /// <summary>
        ///登陆超时
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorTimeOut()
        {
            return new RedirectResult("/Error/TimeOut");
        }
        /// <summary>
        ///404 没有找到
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorNotFound()
        {
            return new RedirectResult("/Error/NotCustFound");
        }
        /// <summary>
        ///没有权限
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorNotAuthorize()
        {
            return new RedirectResult("/Error/NotAuthorize");
        }
        /// <summary>
        ///自定义消息
        /// </summary>
        /// <returns></returns>
        protected ActionResult ErrorCustomMsg(string strmsg)
        {
            return new RedirectResult($"/Error/CustomerMsg?msg= {HttpUtility.UrlEncode( strmsg)}");
           
        }
        #endregion

        #region 私有方法

        /// <summary>
        /// 获取当前UserId
        /// </summary>
        /// <returns></returns>
        public static string GetUserId()
        {
            if (App.User == null) return String.Empty;
            return App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
        }

        public static string GetRealName()
        {
            if (App.User == null) return String.Empty;
            return App.User.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
        }

        public static string GetUserName()
        {
            if (App.User == null) return String.Empty;
            return App.User.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value;
        }

        public static string GetUserType()
        {
            if (App.User == null) return String.Empty;
            return App.User.FindFirst(ClaimConst.CLAINM_SUPERADMIN)?.Value;
        }

        private void GetUserMenu(string userId)
        {
            IList<SysMenuEntity> menulist = null;
            Scoped.Create((_, scope) =>
            {
                var services = scope.ServiceProvider;
                var _menuService = App.GetService<ISysMenuService>(services);
                menulist = _menuService.GetUserPartMenu(userId.ParseToLong(), 0);

                menulist = GetDistinctMenu(menulist,userId);
                List<SysMenuModel> lsetm = new List<SysMenuModel>();
                if (menulist != null)
                {
                    var onemenulist = menulist.Where(w => w.Menulevel == 0);
                    foreach (var item in onemenulist)
                    {
                        SysMenuModel etm = new SysMenuModel();
                        etm.id = item.Id;
                        etm.title = item.MenuName;
                        etm.href = item.MenuUrl;
                        etm.type = 0;
                        etm.isMenu = item.Isvisible.Value;
                        etm.icon = "layui-icon " + item.MenuIcon;
                        GetUserChildrenMenu(etm, menulist, item.Id);
                        lsetm.Add(etm);
                    }
                }
                CurentMenu = lsetm;
                _cache.SetAsync("CurentMenu_" + userId, lsetm);
            });

        }
        private void GetUserChildrenMenu(SysMenuModel etmModel, IList<SysMenuEntity> listpartmenu, long pid)
        {
            var children = listpartmenu.Where(w => w.ParentId == pid);
            if (children != null && children.Count() > 0)
            {
                etmModel.children = new List<SysMenuModel>();

                foreach (var item in children)
                {
                    SysMenuModel etm = new SysMenuModel();
                    etm.id = item.Id;
                    etm.title = item.MenuName;
                    etm.icon = "layui-icon " + item.MenuIcon;
                    etm.href = item.MenuUrl;
                    etm.isMenu = item.Isvisible.Value;
                    etm.openType = item.TargetType == 0 ? "_iframe" : "_blank";
                    GetUserChildrenMenu(etm, listpartmenu, item.Id);

                    etm.type = (etm.children != null && etm.children.Count > 0) ? 0 : 1;
                    etmModel.children.Add(etm);
                }
            }
        }

        private List<SysMenuEntity> GetDistinctMenu(IList<SysMenuEntity> sysMenuList,string userId)
        {
            Dictionary<string, List<string>> dicPower = new Dictionary<string, List<string>>();
            List<SysMenuEntity> list = new List<SysMenuEntity>();
            foreach (var item in sysMenuList)
            {
                if (list.Where(w => w.MenuCode == item.MenuCode).FirstOrDefault() == null)
                {
                    list.Add(item);
                    var powerls = dicPower.ContainsKey(item.MenuCode) ? dicPower[item.MenuCode] : new List<string>();
                    if (!string.IsNullOrEmpty(item.Funcode))
                    {
                        string[] powers = item.Funcode.Split(',');
                        for (int i = 0; i < powers.Length; i++)
                        {
                            if (!powerls.Contains(powers[i]))
                            {
                                powerls.Add(powers[i]);
                            }
                        }
                        dicPower[item.MenuCode] = powerls;
                    }

                }
                else
                {
                    var powerls = dicPower.ContainsKey(item.MenuCode) ? dicPower[item.MenuCode] : new List<string>();

                    if (!string.IsNullOrEmpty(item.Funcode))
                    {
                        string[] powers = item.Funcode.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < powers.Length; i++)
                        {
                            if (!powerls.Contains(powers[i]))
                            {
                                powerls.Add(powers[i]);
                            }
                        }
                        dicPower[item.MenuCode] = powerls;
                    }

                }
            }
            CurentMenuPower = dicPower;
            _cache.SetAsync("CurentPower_" + userId, dicPower);
            list.Sort((a, b) => { return a.MenuSeq - b.MenuSeq; });
            return list;
        }
        #endregion

        #region 权限验证
        public bool SysPower(string menuCode, string funCode, string userId, bool isRedirect = true)
        {

            bool result = true;
            if ("999999" == userId)//管理员
            {
                result = true;
            }
            else if (!CurentMenuPower.ContainsKey(menuCode) || !CurentMenuPower[menuCode].Contains(funCode))
            {
                result = false;
            }
            if (isRedirect && !result)
            {
                Response.Redirect("/Error/NotAuthorize");
            }
            return result;
        }
        public bool SysPower(List<string> menuCodeList, string funCode, string userId, bool isRedirect = true)
        {

            bool result = false;
            if ("999999" == userId)//管理员
            {
                result = true;
            }
            else
            {
                foreach (var menuCode in menuCodeList)
                {
                    if (CurentMenuPower.ContainsKey(menuCode) && CurentMenuPower[menuCode].Contains(funCode))
                    {
                        result = true;
                        break;
                    }
                }
            }
            if (isRedirect && !result)
            {
                Response.Redirect("/Error/NotAuthorize");
            }
            return result;
        }
        #endregion
    }
}
